//
//  STLLoadMv.m
//  STL_ Animation
//
//  Created by 孙健 on 16/4/13.
//  Copyright © 2016年 STL. All rights reserved.
//

#import "STLLoadMv.h"

//保存的文件名
#define STLfileName(url) url

// 缓存主目录
#define HSCachesDirectory [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"STLCache"]

// 文件的已下载长度
#define HSDownloadLength(url) [[[NSFileManager defaultManager] attributesOfItemAtPath:HSFileFullpath(url) error:nil][NSFileSize] integerValue]

// 文件的存放路径（caches）
#define HSFileFullpath(url) [HSCachesDirectory stringByAppendingPathComponent:STLfileName(self.filename)]

// 存储文件总长度的文件路径（caches）
#define HSTotalLengthFullpath [HSCachesDirectory stringByAppendingPathComponent:@"self.filename"]

@interface STLLoadMv ()<NSURLSessionDelegate,NSURLSessionDownloadDelegate>

//保存所有的任务
@property (nonatomic, strong) NSMutableDictionary *dictionaryTasks;
//保存所有的下载的相关信息
@property (nonatomic, strong) NSMutableDictionary *dictionaryModel;
@property (nonatomic, strong) NSString *filename;
@end

@implementation STLLoadMv

- (CGFloat)progress:(NSString *)url {
    return 100;
}

- (NSMutableDictionary *)dictionaryTasks {
    
    if (!_dictionaryTasks) {
        
        _dictionaryTasks = [NSMutableDictionary dictionary];
    }
        
    return _dictionaryTasks;
    
}

- (NSMutableDictionary *)dictionaryModel {
    
    if (!_dictionaryModel) {
        
        _dictionaryModel = [NSMutableDictionary dictionary];
    }
    return _dictionaryModel;
}

static STLLoadMv *loadmv;
+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        loadmv = [[self alloc] init];
    });
    
    return loadmv;
}




/**
 *  开启任务下载资源
 */
- (void)download:(NSString *)url progress:(void (^)(CGFloat))progressBlock state:(void (^)(DownloadState))stateBlock
{
    if (!url) return;
    if ([self isCompletion:url]) {
        stateBlock(DownloadStateEnd);
        NSLog(@"----该资源已下载完成");
        return;
    }
    // 暂停
    if ([self.dictionaryTasks valueForKey:url]) {
        [self handle:url];
        
        return;
    }
    
    NSURLSessionConfiguration *configu = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configu delegate:self delegateQueue:nil];
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    
    // 创建一个Data任务
    NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request];
    NSUInteger taskIdentifier = arc4random() % ((arc4random() % 10000 + arc4random() % 10000));
    [task setValue:@(taskIdentifier) forKeyPath:@"taskIdentifier"];
    
    // 保存任务
    [self.dictionaryTasks setValue:task forKey:url];
    
    STLoadModel *model = [[STLoadModel alloc] init];
    model.url = url;
    model.progressBlock = progressBlock;
    model.stateBlock = stateBlock;
   [self.dictionaryModel setValue:model forKey:@(task.taskIdentifier).stringValue];
    [self start:url];
}


- (void)handle:(NSString *)url
{
    NSURLSessionDownloadTask *task =[self getTask:url];
    if (task.state == NSURLSessionTaskStateRunning) {
        [self pause:url];
    } else {
        [self start:url];
    }
}

/**
 *  开始下载
 */
- (void)start:(NSString *)url
{
    NSURLSessionDownloadTask *task = [self getTask:url];
    [task resume];
    
    [self getSessionModel:task.taskIdentifier].stateBlock(DownloadStateStart);
}

/**
 *  暂停下载
 */
- (void)pause:(NSString *)url
{
    NSURLSessionDownloadTask *task = [self getTask:url];
    [task suspend];
    
    [self getSessionModel:task.taskIdentifier].stateBlock(DownloadStateStop);
}

/**
 *  根据url获得对应的下载任务
 */
- (NSURLSessionDownloadTask *)getTask:(NSString *)url
{
    return (NSURLSessionDownloadTask *)[self.dictionaryTasks valueForKey:url];
}

/**
 *  根据url获取对应的下载信息模型
 */
- (STLoadModel *)getSessionModel:(NSUInteger)taskIdentifier
{
    return (STLoadModel *)[self.dictionaryModel valueForKey:@(taskIdentifier).stringValue];
}

/**
 *  判断该文件是否下载完成
 */
- (BOOL)isCompletion:(NSString *)url
{
    if ([self fileTotalLength]) {
        return YES;
    }
    return NO;
}

/**
 *  获取该资源总大小
 */
- (NSInteger)fileTotalLength
{
    return [[NSDictionary dictionaryWithContentsOfFile:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]][self.filename] integerValue];
}


#pragma mark - ----------下载de进度条的协议方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    
    STLoadModel *sessionModel = [self getSessionModel:downloadTask.taskIdentifier];
    
   // NSLog(@"%lld", totalBytesWritten * 100/totalBytesExpectedToWrite);
    CGFloat progress = totalBytesWritten * 100/ totalBytesExpectedToWrite;
    sessionModel.progressBlock(progress);
}




/**
 * 请求完毕（成功|失败）
 */

#pragma mark - ------------下载的协议方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    
    self.filename = downloadTask.response.suggestedFilename;
    NSString *name = [self.filename stringByReplacingOccurrencesOfString:@".flv" withString:@".mp4"];
    NSString  *filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:name];
    
    
    
    
    NSURL *toURL = [NSURL fileURLWithPath:filepath];
    [[NSFileManager defaultManager] copyItemAtURL:location toURL:toURL error:nil];
    [session invalidateAndCancel];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"download" object:nil];
  
    NSLog(@"%@", filepath);
   

    [self.delegate getfilename:filepath];
    STLoadModel *sessionModel = [self getSessionModel:downloadTask.taskIdentifier];

    NSLog(@"下载完成");
    sessionModel.stateBlock(DownloadStateEnd);
         // 清除任务
    [self.dictionaryTasks removeObjectForKey:sessionModel.url];
    [self.dictionaryModel removeObjectForKey:@(downloadTask.taskIdentifier).stringValue];
}


@end
